/*
	YoghurtGum - 2D Game Engine

	Copyright 2009-2011 Quinten Lansu
	
	Licensed under the Apache License, Version 2.0 (the "License"); you may not 
	use this file except in compliance with the License. You may obtain a copy 
	of the License at 
		
		http://www.apache.org/licenses/LICENSE-2.0 
		
	Unless required by applicable law or agreed to in writing, software 
	distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
	License for the specific language governing permissions and limitations 
	under the License. 
*/

#ifndef _YGLOG_H_
#define _YGLOG_H_

#include "YGSources.h"
#include "YGGeneralMath.h"
#include "YGDevice.h"
#include "YGLogStream.h"

namespace YoghurtGum
{

	class FileManager;

#if (YG_RUN == YG_RUN_DEBUG)

	#define YG_LOG_DEBUG(msg, ...)    Log::GetSingleton().Print(msg, __VA_ARGS__)

#else

	#define YG_LOG_DEBUG(msg, ...)

#endif

#if (YG_COMPILER_TYPE == YG_COMPILER_TYPE_MSVC)

	struct LogSpecial { int x; };
	static const LogSpecial ENDL;

#elif (YG_COMPILER_TYPE == YG_COMPILER_TYPE_GPP)

	/*class LogSpecial 
	{ 

	public:

		LogSpecial() { }
		~LogSpecial() { }

		int m_Empty;

	};*/
	struct LogSpecial { int x; };
	static const LogSpecial ENDL = { 1 };

#endif

	class Log
	{

	public:

		enum Level
		{
			LEVEL_INFO,
			LEVEL_TRACE,
			LEVEL_ERROR,
			LEVEL_FATAL,
			LEVEL_ALL
		};
		
		void OpenFile();

		static Log& GetSingleton();

		static void SetInstance(Log* a_Instance);

		/*
			Parses everything Date::Format parses.

			Specific flags:
			$lel    = Error level
			$lEL    = Error level uppercase
			$lmsg   = The message
			
			Standard:
			($TIME) - $EL - $msg
		*/
		void SetFormat(char* a_Format);

		void SetModule(char* a_ModuleName);

		void Print(char* a_Message, ...);

		Log& operator << (LogSpecial a_Special);

		Log& operator << (char a_Character);
		Log& operator << (char* a_Message);
		Log& operator << (const char* a_Message);

#if YG_OS_TYPE == YG_OS_TYPE_WINDOWSMOBILE

		Log& operator << (std::string a_Message);
		Log& operator << (wchar_t a_Message);
		Log& operator << (wchar_t* a_Message);
		Log& operator << (const wchar_t* a_Message);

#endif

		Log& operator << (float a_Number);
		Log& operator << (unsigned long a_Number);
		Log& operator << (int a_Number);

	private:

		Log();
		~Log();

		void Clear();
		void AppendString(const char* a_String);
		void Output(char* a_Message);
		char* Format(char* a_Message, Level a_Level = LEVEL_INFO);

		static Log* s_Instance;

		char m_Message[YG_LOG_SIZE];
		char m_Formatted[YG_LOG_SIZE];
		char m_Format[4][256];
		char m_Module[256];
		int	 m_Current;

		char  m_Filename[256];
		FILE* m_File;

#ifdef YG_LOG_EMULATOR

		char  m_FilenameEmulator[256];
		FILE* m_FileEmulator;

#endif
	
	}; // class Log

}; // namespace YoghurtGum

#endif
